Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve performance of glTFLoader._applyExtensions #15913

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Starryi
Copy link
Contributor

@Starryi Starryi commented Nov 29, 2024

Cache extensions by _getActiveExtensionsHasOwnFunction

for a specific function name, cache extensions which are enabled and have the specific function, avoid repeated traversals

ILoaderProperty._activeLoaderExtensionFunctions

use Map to replace {} for ILoaderProperty._activeLoaderExtensionFunctions, to imporve has/set/delete operation

for specific p and fName, Just ensure avoid recursive call of applyExtension(p, fName, ...)

Let's say there is an enabled extension which name is extensionA and has function loadSomeAsyc.

For a specific property p,

First, applyExtension(p, fName, ...) should not be called recursively.
In other words, the following trace should not occur:

applyExtension(p, 'loadSomeAsyc') 

             -> ... 

                   -> applyExtension(p, 'loadSomeAsyc') 

                            -> ... 

Second, extensionA.loadSomeAsyc(p, ...) should not be called recursively.
In other words, the following trace should not occur:

applyExtension(p, 'loadSomeAsyc') 

       -> extensionA.loadSomeAsyc(p) 

             -> ... 

                   -> applyExtension(p, 'loadSomeAsyc') 

                         -> extensionA.loadSomeAsyc(p)

                                 -> ... 

so, just ensue no recursive call of applyExtension(p, 'loadSomeAsyc'), two goals can be achieved at the same time.

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s).
To prevent this PR from going to the changelog marked it with the "skip changelog" label.

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

Visualization tests for WebGL 1 have failed. If some tests failed because the snapshots do not match, the report can be found at

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/15913/merge/testResults/webgl1/index.html

If tests were successful afterwards, this report might not be available anymore.

@bjsplat
Copy link
Collaborator

bjsplat commented Nov 29, 2024

Visualization tests for WebGL 1 have failed. If some tests failed because the snapshots do not match, the report can be found at

https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/15913/merge/testResults/webgl1/index.html

If tests were successful afterwards, this report might not be available anymore.

@bghgary
Copy link
Contributor

bghgary commented Dec 2, 2024

Thanks for the PR. Just curious, have you seen measurable performance issues with this code?

@alexchuber also recently identified an issue with the loader extension ordering that needs to be addressed. It might be good to think about both of these issues together before making a complete fix for both as they will likely touch the same code.

loaderProperty._activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions || new Map();
const activeLoaderExtensionFunctions = loaderProperty._activeLoaderExtensionFunctions;

if (!activeLoaderExtensionFunctions.has(functionName)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this won't work. Indexing by only functionName and not ${extension.name}.${functionName} means that, if an object needs the same function applied to it from several extensions, only one will be applied.
E.g., a material using KHR_materials_volume will always also have either KHR_materials_transmission or KHR_materials_diffuse_transmission, both of which use the function _loadMaterialPropertiesAsync.
When fixing this issue, try testing with this asset. If it looks correct when loaded in the Sandbox, you've probably solved the issue.

I do agree that we should find a way to avoid recursively applying extensions, since it results in unexpected behavior with the order in which extensions are applied. E.g., we expect that KHR_materials_volume is applied after the two transmission extensions mentioned above. However, if you look at the order property of these 3 extensions, you'll see that it's wrong (it's reversed) and shouldn't possibly work.
But the recursion just conveniently masks this problem by un-reversing the order, thus making it correct. AKA it's two bugs cancelling each other out :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, forgot to clarify:
You will need to update the order of extensions once the recursion has been removed.
At minimum, we know that volume will need to have an order higher than both transmission and diffuse transmission.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants